【CDI】DBへのデータ書き込みをロールバックさせる方法

【CDI】DBへのデータ書き込みをロールバックさせる方法

Clock Icon2024.09.05

はじめに

こんにちは、データ事業本部の渡部です。

今回はInformaticaのCloud Data Integration(以降、CDI)でDBへのデータ書き込みが異常終了した時にロールバックさせる方法をご紹介します。
「再実行でのリカバリが認められない」「全件ロールバックできるならしたいなあ」などの要件がある場合に、今回の記事はご参考になるかなと思います。
またInformaticaには設定が多くありますが、実際に全部を理解するのは難しいので、その一助となれば幸いです。

ロールバックの設定

Informaticaにはロールバックに関わる設定として、検証をとおして以下の設定があることがわかりました。

  • エラー時にトランザクションをロールバック
  • エラー時に停止
  • コミット間隔
  • コミットタイプ

それぞれの設定について、本記事でどのような動きをするのか実際にご紹介します。
検証では以下のようにS3のファイル→DB(Oracle)の簡単マッピングを使用します。

mapping

ターゲットDBのテーブル項目IDをPKとして、ソースデータにPKを重複させる行を用意させてエラーを発生させます。
ロールバックの設定はマッピングタスクの詳細セッションプロパティで設定します。

mappingtask

それぞれの設定について見ていきます。

エラー時にトランザクションをロールバック

Informaticaのドキュメントを確認します。

タスクが非致命的エラーに遭遇した場合、次のコミットポイントでトランザクションをロールバックします。
タスクが変換エラーに遭遇した場合、そのエラーがターゲットの有効なトランザクション生成後に発生した場合は、トランザクションをロールバックします。

まとめると、異常終了時にロールバックを有効化する設定となります。
ちなみにInformaticaにおけるエラーの種類としては以下となります。

  • 致命的エラー:DB接続失敗のような根本的なエラー
  • 非致命的エラー:PK重複やデータ型不一致のエラー

エラー時に停止

Informaticaのドキュメントを確認します。

タスクがセッションを停止する前に遭遇できる非致命的エラーの数を示します。非致命的エラーには、リーダーエラー、ライターエラー、およびDTMエラーが含まれます。
セッションを停止する前に許容する非致命的エラーの数を入力してください。タスクは、各ソース、ターゲット、および変換ごとに独立したエラーカウントを保持します。0を指定した場合、非致命的エラーが発生してもセッションは停止しません。

まとめると、ジョブを停止させるまでの非致命的エラーの発生数を定義する設定となります。

コミット間隔

Informaticaのドキュメントを確認します。

コミット間の行数間隔。
コミット間隔を設定しない場合、タスクは10,000行ごとにコミットを行います。

まとめると、何行ごとにトランザクションをコミットするかの設定となります。

コミットタイプ

Informaticaのドキュメントを確認します。

Source(ソース): タスクはソース行の数に基づいてコミットを行います。
Target(ターゲット): タスクはターゲット行の数に基づいてコミットを行います。
User Defined(ユーザー定義): タスクはVisioテンプレートで定義されたコミットロジックに基づいてコミットを行います。

まとめると、ソースまたはターゲットのどちらの行数にもとづいてコミットをするかを定義する設定となります。
なおユーザー定義については、直近のリリースでVisioテンプレートが廃止されたので、現状は使用できない機能だと推測します。
デフォルトはTargetのため、変更の必要がなければそのままで問題ありません。


上記の設定を組み合わせて、ロールバックを検証しました。
今回はコミットタイプをデフォルトで実施するため、エラー時のトランザクションをロールバックエラー時に停止コミット間隔のロールバック3点セットを使用しています。

設定別に見るコミット数

設定の組み合わせ別で実際にどの行がコミットされるかどうかを試した結果をまとめました。
ソースデータとして30010行を用意して、ターゲットDBのPK重複を発生させるエラー行を入れています。
ソース定義・ターゲット定義は同一です。

No.1

こちらの設定ではエラー行が含まれているトランザクションがロールバックされました。
コミット間隔を10000に設定しているのに10192行間隔でコミットされているのが疑問ですが、指定したコミット間隔でトランザクション単位でロールバックされていること、1度エラーがあっても処理が動き続けていることが確認できます。
またジョブステータスも成功となっているのが特徴です。

commit_rows21

No.2

No.1との設定と比べて、エラー時にトランザクションをロールバックを無効化しています。
こちらはトランザクション単位ではロールバックされずに、エラー行のみがコミットされず、他の行はすべてコミットされました。
ジョブステータスは警告となります。

commit_rows22

No.3

No.1と比べて、エラー時に停止を1としています。
非致命的エラーが1回発生したあとにジョブを停止させる機能なので、エラー行が含まれるあとのトランザクションもコミットされていません。
ジョブステータスは失敗となりました。

commit_rows23

No.4

No.3と比べて、コミット間隔を50000としています。
ソース行数 < コミット間隔 となり、ソース行全体が一つのトランザクションとなるため、ソース行全体がロールバックされました。
全件ロールバックをする場合は、こちらの設定をすればよいことがわかりました。

commit_rows24

No.5

No.3と同じ設定です。
ソース行の501行目にエラー行を差し込み、1回目のトランザクションでエラーが発生するようにしました。
こちらは予想どおりとなりますが、1回目のトランザクションはロールバックされ、エラー時に停止を1としているため、以降のトランザクションは実行されずコミットされませんでした。

commit_rows25

注意事項

今回検証するのに使用したDBはOracleのため、他のDBでは必要な設定が異なるかもしれません。
実装時に実際にロールバックされるかをご確認いただければと思います。

またコミット間隔の上限は「2,147,483,647」とInformatica社から回答をいただきました。
これ以上の行数にはロールバックが適用されないので注意が必要です。
なおそもそもコミット間隔を広げすぎるとデータベースログが肥大して処理がエラーとなってしまう場合もあります。
参考:Target-Based Commit

まとめ

以上、ロールバック3点セットを使用したコミット行の動きでした。

編集後記となりますが、実はこの記事をまとめるのに100回以上ジョブを実行させて試行錯誤したので、なかなか骨の折れる検証でした・・・。
この記事がどなたかの試行数を減らせれば幸いです。

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.